package com.zrw.common.utils;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializer;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import com.fasterxml.jackson.databind.ser.impl.ObjectIdWriter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.fasterxml.jackson.databind.ser.std.BeanSerializerBase;
import com.zrw.common.config.AppConfig;
import com.zrw.common.core.domain.model.LoginUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.*;

public class JsonUtils {

    public static final ObjectMapper objectMapper = new ObjectMapper();
    private static final Logger log = LoggerFactory.getLogger(JsonUtils.class);

    public static ObjectMapper getObjectMapper() {
        return objectMapper;
    }

    public static String toJsonString(Object value) {
        try {
            return objectMapper.writeValueAsString(value);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("json序列化失败", e);
        }
    }

    public static String toJsonString(Object value, String[] excludeFields) {
        try {
            ObjectMapper mapper = new ObjectMapper();

            // 使用 BeanSerializerModifier 来忽略字段
            mapper.setSerializerFactory(mapper.getSerializerFactory()
                    .withSerializerModifier(new BeanSerializerModifier() {
                        @Override
                        public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
                                                                         BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
                            List<BeanPropertyWriter> list = new ArrayList<>();
                            for (BeanPropertyWriter beanProperty : beanProperties) {
                                String name = beanProperty.getName();
                                if (!Arrays.asList(excludeFields).contains(name)) {
                                    list.add(beanProperty);
                                }
                            }
                            return list;
                        }}));
            // 序列化对象
            return mapper.writeValueAsString(value);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("json序列化失败", e);
        }
    }

    public static <T> T parseObject(String str, Class<T> cClass) {
        if (StringUtils.isEmpty(str)) {
            return null;
        }

        try {
            return objectMapper.readValue(str, cClass);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("json反序列化失败", e);
        }
    }
    public static <T> T parseObject(String str, JavaType javaType) {
        if (StringUtils.isEmpty(str)) {
            return null;
        }

        try {
            return objectMapper.readValue(str, javaType);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("json反序列化失败", e);
        }
    }

    public static <T> List<T> parseArray(String str, Class<T[]> clazz){
        if (StringUtils.isEmpty(str)) {
            return Collections.emptyList();
        }

        T[] result = null;
        try {
            result = objectMapper.readValue(str, clazz);
        } catch (Exception e) {
            throw new RuntimeException("json反序列化失败", e);
        }
        if (result == null) {
            return Collections.emptyList();
        }
        return Arrays.asList(result);
    }


    public static JsonNode parseJson(String str) {
        JsonNode jsonNode = null;
        try {
            jsonNode = objectMapper.readTree(str);
        } catch (Exception e) {
            throw new RuntimeException("json反序列化失败", e);
        }
        return jsonNode;
    }
}
